package com.netty.rpc.reporter;

import io.netty.util.concurrent.FastThreadLocalThread;
import io.netty.util.internal.PlatformDependent;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
@Component
public class DirectMemoryReporter {

    private static final ScheduledExecutorService EXECUTOR_SERVICE = Executors.newScheduledThreadPool(1);

    private static final int _1K = 1024;

    private static final String BUSINESS_KEY = "netty_direct_memory";

    private AtomicLong directMemory;

    private Long directMemoryMax;



    @PostConstruct
    public void init(){
        Field field1 = ReflectionUtils.findField(PlatformDependent.class, "DIRECT_MEMORY_COUNTER");
        Field field2 = ReflectionUtils.findField(PlatformDependent.class, "DIRECT_MEMORY_LIMIT");
        field1.setAccessible(true);
        field2.setAccessible(true);
        try {
            directMemory = (AtomicLong) field1.get(PlatformDependent.class);
            directMemoryMax = (Long)field2.get(PlatformDependent.class);
            startReport();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void startReport(){
        EXECUTOR_SERVICE.scheduleAtFixedRate(() ->{
            try{
                int memoryInKb = (int)(directMemory.get() /  _1K);
                Long directMemoryMaxKb = directMemoryMax /  _1K;
                log.info("netty used direct memory {}  kb, max direct memory {} kb", memoryInKb, directMemoryMaxKb);
            }catch (Exception e){
               e.printStackTrace();
            }

        }, 0, 1, TimeUnit.SECONDS);
    }


}
